package com.passion.common.util;

import cn.hutool.core.text.StrBuilder;
import cn.hutool.core.util.CharsetUtil;
import com.google.common.collect.Maps;
import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;

import java.util.Map;

/**
 * 拼音工具类
 *
 * @author 中国印
 * @since 2022年05月11日 13:46:00
 */
public class PinyinUtil {

    private PinyinUtil() {
    }

    public static String getAllFirstLetter(String chinese) {
        if (StringUtils.isBlank(chinese)) {
            return "";
        } else {
            int len = chinese.length();
            StrBuilder strBuilder = new StrBuilder(len);

            for(int i = 0; i < len; ++i) {
                strBuilder.append(getFirstLetter(chinese.charAt(i)));
            }

            return strBuilder.toString();
        }
    }

    public static char getFirstLetter(char ch) {
        if (ch >= 'a' && ch <= 'z') {
            return ch;
        } else if (ch >= 'A' && ch <= 'Z') {
            return Character.toLowerCase(ch);
        } else {
            byte[] bys = String.valueOf(ch).getBytes(CharsetUtil.CHARSET_GBK);
            if (bys.length == 1) {
                return '*';
            } else {
                int count = (bys[0] + 256) * 256 + bys[1] + 256;
                if (count < 45217) {
                    return '*';
                } else if (count < 45253) {
                    return 'a';
                } else if (count < 45761) {
                    return 'b';
                } else if (count < 46318) {
                    return 'c';
                } else if (count < 46826) {
                    return 'd';
                } else if (count < 47010) {
                    return 'e';
                } else if (count < 47297) {
                    return 'f';
                } else if (count < 47614) {
                    return 'g';
                } else if (count < 48119) {
                    return 'h';
                } else if (count < 49062) {
                    return 'j';
                } else if (count < 49324) {
                    return 'k';
                } else if (count < 49896) {
                    return 'l';
                } else if (count < 50371) {
                    return 'm';
                } else if (count < 50614) {
                    return 'n';
                } else if (count < 50622) {
                    return 'o';
                } else if (count < 50906) {
                    return 'p';
                } else if (count < 51387) {
                    return 'q';
                } else if (count < 51446) {
                    return 'r';
                } else if (count < 52218) {
                    return 's';
                } else if (count < 52698) {
                    return 't';
                } else if (count < 52980) {
                    return 'w';
                } else if (count < 53689) {
                    return 'x';
                } else if (count < 54481) {
                    return 'y';
                } else {
                    return count < 55290 ? 'z' : ' ';
                }
            }
        }
    }

    /**
     * 方法说明：将给定字符串中的中文汉字转换成拼音(拼音全小写)
     *
     * @param str 给定的字符串
     * @return {@link String } 若转换异常，返回 字符串 xx
     */
    public static String transferChineseWordToPinyin(String str) {
        HanyuPinyinOutputFormat pyFormat = new HanyuPinyinOutputFormat();
        pyFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);
        pyFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
        pyFormat.setVCharType(HanyuPinyinVCharType.WITH_V);
        try {
            return PinyinHelper.toHanYuPinyinString(str, pyFormat, "", true);
        } catch (BadHanyuPinyinOutputFormatCombination e) {
            e.printStackTrace();
        }
        return "x";
    }

    /**
     * 方法说明：给定一个字符串，返回字符串中的中文汉字转成拼音首字母大写后的字符串
     *
     * @param str           给定的字符串
     * @param isWordFirstUp 汉字转的拼音首字母是否要大写
     * @return {@link String }
     */
    public static String transferToPinyin(String str, boolean isWordFirstUp) {
        if (StringUtils.isBlank(str)) {
            return str;
        }
        Map<String, String> chineseWordPinyinMap = getChineseWordPinyinMap(str, isWordFirstUp);
        if (!chineseWordPinyinMap.isEmpty()) {
            for (String key : chineseWordPinyinMap.keySet()) {
                String value = chineseWordPinyinMap.get(key);
                str = str.replace(key, value);
            }
        }
        return str;
    }

    /**
     * 方法说明：给定一个字符串，返回字符串中的中文汉字对应的拼音缓存集合
     *
     * @param str           给定的字符串
     * @param isWordFirstUp 汉字转的拼音首字母是否要大写
     * @return {@link String }
     */
    public static Map<String, String> getChineseWordPinyinMap(String str, boolean isWordFirstUp) {
        Map<String, String> retMap = Maps.newHashMap();
        // 如果包含中文
        if (StringUtils.isContainChinese(str)) {
            String chineseWords = StringUtils.getChineseWords(str);
            String[] words = chineseWords.split("");
            for (String word : words) {
                if (isWordFirstUp) {
                    String s = transferChineseWordToPinyin(word);
                    retMap.put(word, StringUtils.toUpperFirstCharacter(s));
                } else {
                    retMap.put(word, transferChineseWordToPinyin(word));
                }
            }
        }
        return retMap;
    }

    public static void main(String[] args) {
        String s = "，.中文de汉字include英,。文hun合";
        String result = transferToPinyin(s, true);
        // ，.ZhongWendeHanZiincludeYing,。WenhunHe
        System.out.println(result);
    }
}